﻿namespace NTLib.Pipe.Network.Targets
{
    using NTLib.Pipe.Targets;
    using NTLib.Core.Reflection;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using NTLib.Pipe.Descriptors;
    using System.Threading;
    using NTLib.Pipe.Network.Descriptors;
    using System.Diagnostics;
    using NTLib.Pipe.Network.Connectors;
    using NTLib.Pipe.Network.Formats;
    using NTLib.Core.Attributes;
    using Streaming.Formats;

    /// <summary>
    /// Provide target definition for http target.
    /// </summary>
    [Guid("95f1356d-8d22-4b42-bd5f-4cbd4ea989eb")]
    public class HttpNetworkTargetProvider : ITargetProvider
    {
        #region Fields
        
        private readonly static HttpNetworkTargetProvider s_instance = new HttpNetworkTargetProvider();
        private readonly Type[] s_types = { typeof(HttpInfo) };
        private readonly Guid _id;

        private readonly NetworkConnectorDescription _connectorDesc;
        private readonly NetworkFormatDescription _formaterHttpDesc;

        #endregion

        #region Ctor

        /// <summary>
        /// Prevents a default instance of the <see cref="HttpNetworkTargetProvider"/> class from being created.
        /// </summary>
        private HttpNetworkTargetProvider()
        {
            this._connectorDesc = new NetworkConnectorDescription(ConnectorManager.Instance.Register<HttpConnector>(), "HTTP");
            this._formaterHttpDesc = new NetworkFormatDescription(PackageFormatManager.Instance.Register<HttpPackageFormats>(), "HTTP");
            this._id = this.GetType().GetMandatoryAttribute<GuidAttribute>().Value;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the identifier.
        /// </summary>
        public Guid Id
        {
            get { return this._id; }
        }

        /// <summary>
        /// Gets the information type managed.
        /// </summary>
        public IEnumerable<Type> InfoTypeManaged
        {
            get { return s_types; }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is enabled.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is enabled; otherwise, <c>false</c>.
        /// </value>
        public bool IsEnabled
        {
            get { return true; }
        }

        /// <summary>
        /// Gets the instance.
        /// </summary>
        public static ITargetProvider Instance
        {
            get { return s_instance; }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Locates the asynchronous.
        /// </summary>
        public Task<IEnumerable<ITargetDescriptor>> LocateAsync<U>(U information, CancellationToken token = default(CancellationToken))
        {
            HttpInfo info = (HttpInfo)(object)information;

            NetworkTargetDescription target = new NetworkTargetDescription(this._connectorDesc, this._formaterHttpDesc, info, false, Guid.NewGuid());
            return Task.FromResult<IEnumerable<ITargetDescriptor>>(new List<ITargetDescriptor>() { target });
        }
     
        #endregion
    }
}
